import * as THREE from "three"
import SettingsData from "../data/SettingsData"
import { TourTransitionDirection, TourTransitionType } from "../enum/tourTransition.enum"
import Vectors from "../three/Vectors"
import TourTransitionFactory from "./TourTransitionFactory"
export default class TourPanTransition {
  settingsData: SettingsData
  rotate: any
  stopRotating: any
  type: number
  toIndex: number
  currentTransitionPromise: any
  onStopRequested: () => Promise<void>
  getPanDirection: (e: any, t: any) => number
  constructor(e, t, i) {
    this.settingsData = e
    this.rotate = t
    this.stopRotating = i
    this.type = TourTransitionType.Burns
    this.toIndex = -1
    this.currentTransitionPromise = null
    this.onStopRequested = () => Promise.resolve()
    this.getPanDirection = (e, t) => {
      let i = TourTransitionDirection.Right
      if (
        e &&
        e.metadata.scanId &&
        e.metadata.cameraQuaternion &&
        e.metadata.cameraPosition &&
        t &&
        t.metadata.scanId &&
        t.metadata.cameraPosition &&
        t.metadata.cameraQuaternion
      ) {
        const s = Vectors.FORWARD.clone().applyQuaternion(e.metadata.cameraQuaternion),
          n = t.metadata.cameraPosition,
          r = e.metadata.cameraPosition
        let o = n.clone().sub(r).normalize()
        o.lengthSq() < 0.00001 && (o = Vectors.FORWARD.clone().applyQuaternion(t.metadata.cameraQuaternion)),
          s.cross(o).y > 0 && (i = TourTransitionDirection.Left)
      }
      return i
    }
  }
  get active() {
    return null !== this.currentTransitionPromise
  }
  get promise() {
    return this.currentTransitionPromise ? this.currentTransitionPromise : Promise.resolve()
  }
  async stop() {
    this.currentTransitionPromise && (await this.onStopRequested(), await this.promise, (this.currentTransitionPromise = null))
  }
  start(e) {
    if (this.active) throw Error("Transition already active")
    if (!e) throw Error("Tour pan requires two snapshots")
    if (!e.snapshot || !e.nextSnapshot) return (this.currentTransitionPromise = Promise.resolve()), this
    const { deferred: t } = this.build(e.snapshot, e.nextSnapshot, e.panOverrides)
    this.currentTransitionPromise = t.then(() => {
      this.currentTransitionPromise = null
    })
    return this
  }
  build(e, t, i) {
    const { panDirection, panAngle } = i
    const r = TourTransitionFactory.getPanValues(this.settingsData, !1, panDirection, panAngle)
    let o = r.direction
    ;(void 0 !== o && o !== TourTransitionDirection.Auto) || (o = this.getPanDirection(e, t)),
      (this.onStopRequested = async () => {
        await this.stopRotating()
      })
    return {
      deferred: this.rotate(r.ms, new THREE.Vector2(o * r.radiansPerMs, 0))
    }
  }
}
